#include "example.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

JsonData *ParseJsonData(const char *filename) {
	FILE *fp = fopen(filename, "r");
	if (!fp) return NULL;

	fseek(fp, 0, SEEK_END);
	long len = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	char *data = (char *) malloc(len + 1);
	fread(data, 1, len, fp);
	fclose(fp);
	data[len] = '\0';

	cJSON *root = cJSON_Parse(data);
	free(data);
	if (!root) return NULL;

	JsonData *jsonData = (JsonData *) calloc(1, sizeof(JsonData));

	// 解析基本类型
	jsonData->String    = cJSON_GetStringValue(cJSON_GetObjectItem(root, "string"));
	jsonData->Number    = cJSON_GetObjectItem(root, "number")->valueint;
	jsonData->Float     = cJSON_GetObjectItem(root, "float")->valuedouble;
	jsonData->Boolean   = cJSON_GetObjectItem(root, "boolean")->valueint;
	jsonData->NullValue = NULL;

	// 解析数组
	jsonData->Array = ParseArray(cJSON_GetObjectItem(root, "array"));

	// 解析对象
	jsonData->Object = ParseObject(cJSON_GetObjectItem(root, "object"));

	// 空数组和空对象
	jsonData->EmptyArray  = ParseArray(cJSON_GetObjectItem(root, "emptyArray"));
	jsonData->EmptyObject = (EmptyObject) {0};

	// 混合类型数组
	jsonData->MixedTypes = ParseMixedArray(cJSON_GetObjectItem(root, "mixedTypes"));

	cJSON_Delete(root);
	return jsonData;
}

JsonArray ParseArray(cJSON *array) {
	JsonArray result = {0};
	if (!cJSON_IsArray(array)) return result;

	result.Count    = cJSON_GetArraySize(array);
	result.Elements = (ArrayElement *) calloc(result.Count, sizeof(ArrayElement));

	for (size_t i = 0; i < result.Count; i++) {
		cJSON        *item = cJSON_GetArrayItem(array, i);
		ArrayElement *elem = &result.Elements[i];

		if (cJSON_IsString(item)) {
			elem->Type        = AR_ELEMENT_STRING;
			elem->StringValue = strdup(item->valuestring);
		} else if (cJSON_IsNumber(item)) {
			elem->Type     = AR_ELEMENT_INT;
			elem->IntValue = item->valueint;
		} else if (cJSON_IsBool(item)) {
			elem->Type      = AR_ELEMENT_BOOL;
			elem->BoolValue = cJSON_IsTrue(item);
		} else if (cJSON_IsObject(item)) {
			elem->Type                      = AR_ELEMENT_OBJECT;
			elem->ObjectValue               = (ArrayObject *) malloc(sizeof(ArrayObject));
			elem->ObjectValue->NestedObject = strdup(cJSON_GetStringValue(cJSON_GetObjectItem(item, "nestedObject")));
		} else if (cJSON_IsArray(item)) {
			elem->Type                 = AR_ELEMENT_ARRAY;
			elem->ArrayValue           = (IntArray *) malloc(sizeof(IntArray));
			elem->ArrayValue->Count    = cJSON_GetArraySize(item);
			elem->ArrayValue->Elements = (int *) malloc(sizeof(int) * elem->ArrayValue->Count);
			for (size_t j = 0; j < elem->ArrayValue->Count; j++) {
				elem->ArrayValue->Elements[j] = cJSON_GetArrayItem(item, j)->valueint;
			}
		}
	}
	return result;
}

// 其他解析函数类似，限于篇幅省略...
// 实现 ParseObject 函数
JsonObject ParseObject(cJSON *obj) {
	JsonObject result = {0};
	if (!cJSON_IsObject(obj)) return result;

	cJSON *nestedArray = cJSON_GetObjectItem(obj, "nestedArray");
	if (cJSON_IsArray(nestedArray)) {
		result.NestedArray.Count    = cJSON_GetArraySize(nestedArray);
		result.NestedArray.Elements = (NestedArrayElement *) calloc(result.NestedArray.Count, sizeof(NestedArrayElement));
		for (size_t i = 0; i < result.NestedArray.Count; i++) {
			cJSON *item                           = cJSON_GetArrayItem(nestedArray, i);
			result.NestedArray.Elements[i].Id     = cJSON_GetObjectItem(item, "id")->valueint;
			result.NestedArray.Elements[i].Active = cJSON_GetObjectItem(item, "active")->valueint;
		}
	}
	result.Key = strdup(cJSON_GetStringValue(cJSON_GetObjectItem(obj, "key")));
	return result;
}

// 实现 ParseMixedArray 函数
MixedTypesArray ParseMixedArray(cJSON *array) {
	MixedTypesArray result = {0};
	if (!cJSON_IsArray(array)) return result;

	result.Count    = cJSON_GetArraySize(array);
	result.Elements = (MixedElement *) calloc(result.Count, sizeof(MixedElement));

	for (size_t i = 0; i < result.Count; i++) {
		cJSON        *item = cJSON_GetArrayItem(array, i);
		MixedElement *elem = &result.Elements[i];

		if (cJSON_IsString(item)) {
			elem->Type        = MIXED_STRING;
			elem->StringValue = strdup(item->valuestring);
		} else if (cJSON_IsNumber(item)) {
			elem->Type     = MIXED_INT;
			elem->IntValue = item->valueint;
		} else if (cJSON_IsBool(item)) {
			elem->Type      = MIXED_BOOL;
			elem->BoolValue = cJSON_IsTrue(item);
		} else if (cJSON_IsObject(item)) {
			elem->Type = MIXED_OBJECT;
			// 这里可以进一步处理对象类型
		}
	}
	return result;
}

// 实现 PrintArray 函数
void PrintArray(const JsonArray *array) {
	for (size_t i = 0; i < array->Count; i++) {
		const ArrayElement *elem = &array->Elements[i];
		switch (elem->Type) {
			case AR_ELEMENT_STRING:
				printf("String: %s\n", elem->StringValue);
				break;
			case AR_ELEMENT_INT:
				printf("Int: %d\n", elem->IntValue);
				break;
			case AR_ELEMENT_BOOL:
				printf("Bool: %s\n", elem->BoolValue ? "true" : "false");
				break;
			case AR_ELEMENT_OBJECT:
				printf("Object: %s\n", elem->ObjectValue->NestedObject);
				break;
			case AR_ELEMENT_ARRAY:
				printf("Array: ");
				for (size_t j = 0; j < elem->ArrayValue->Count; j++) {
					printf("%d ", elem->ArrayValue->Elements[j]);
				}
				printf("\n");
				break;
		}
	}
}

// 实现 PrintObject 函数
void PrintObject(const JsonObject *obj) {
	printf("Key: %s\n", obj->Key);
	for (size_t i = 0; i < obj->NestedArray.Count; i++) {
		printf("Id: %d, Active: %s\n", obj->NestedArray.Elements[i].Id, obj->NestedArray.Elements[i].Active ? "true" : "false");
	}
}

// 打印混合类型数组
void PrintMixedTypes(const MixedTypesArray *mixed) {
	if (!mixed || !mixed->Elements) {
		printf("MixedTypesArray is empty or null.\n");
		return;
	}

	printf("MixedTypesArray contains %zu elements:\n", mixed->Count);
	for (size_t i = 0; i < mixed->Count; i++) {
		const MixedElement *elem = &mixed->Elements[i];
		switch (elem->Type) {
			case MIXED_NULL:
				printf("  Element %zu: MIXED_NULL\n", i);
				break;
			case MIXED_STRING:
				printf("  Element %zu: MIXED_STRING - Value: %s\n", i, elem->StringValue);
				break;
			case MIXED_INT:
				printf("  Element %zu: MIXED_INT - Value: %d\n", i, elem->IntValue);
				break;
			case MIXED_BOOL:
				printf("  Element %zu: MIXED_BOOL - Value: %s\n", i, elem->BoolValue ? "true" : "false");
				break;
			case MIXED_OBJECT:
				printf("  Element %zu: MIXED_OBJECT - Complex Object:\n", i);
				if (elem->ObjectValue) {
					for (size_t j = 0; j < elem->ObjectValue->Count; j++) {
						const MixedElement *subElem = &elem->ObjectValue->Complex[j];
						switch (subElem->Type) {
							case MIXED_NULL:
								printf("    Sub-Element %zu: MIXED_NULL\n", j);
								break;
							case MIXED_STRING:
								printf("    Sub-Element %zu: MIXED_STRING - Value: %s\n", j, subElem->StringValue);
								break;
							case MIXED_INT:
								printf("    Sub-Element %zu: MIXED_INT - Value: %d\n", j, subElem->IntValue);
								break;
							case MIXED_BOOL:
								printf("    Sub-Element %zu: MIXED_BOOL - Value: %s\n", j, subElem->BoolValue ? "true" : "false");
								break;
							case MIXED_OBJECT:
								printf("    Sub-Element %zu: MIXED_OBJECT - Nested Object\n", j);
								break;
							default:
								printf("    Sub-Element %zu: Unknown type\n", j);
								break;
						}
					}
				} else {
					printf("    Object is null.\n");
				}
				break;
			default:
				printf("  Element %zu: Unknown type\n", i);
				break;
		}
	}
}


void PrintJsonData(const JsonData *data) {
	printf("String: %s\n", data->String);
	printf("Number: %d\n", data->Number);
	printf("Float: %f\n", data->Float);
	printf("Boolean: %s\n", data->Boolean ? "true" : "false");
	printf("NullValue: %p\n", data->NullValue);

	printf("\nArray:\n");
	PrintArray(&data->Array);

	printf("\nObject:\n");
	PrintObject(&data->Object);

	printf("\nMixedTypes:\n");
	PrintMixedTypes(&data->MixedTypes);
}

int main() {
	printf("=== Example C Demo\n");
	JsonData *data = ParseJsonData("etc/example.json");
	if (!data) {
		fprintf(stderr, "Failed to parse JSON\n");
		return 1;
	}

	PrintJsonData(data);

	// 需要添加内存释放代码
	return 0;
}
